package com.ck.client.schedule;

import com.alibaba.fastjson.JSONObject;
import com.ck.client.service.DeviceHeartBeatService;
import com.ck.client.service.DeviceInfoService;
import com.ck.core.lock.LockConstant;
import com.ck.core.lock.RedisDistributeLock;
import com.ck.core.lock.RedisLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
* @Description: 设备状态变更定时任务
* @Author: hf
* @Date:    2019/5/14 16:18
* @Version: 1.0
*/
@Component
public class DeviceStatusJob {
    private Logger logger = LoggerFactory.getLogger(DeviceStatusJob.class);

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private DeviceHeartBeatService deviceHeartBeatService;

    @Autowired
    private RedisDistributeLock redisDistributeLock;

    @Value("${custom.device.report.time.redundancy:900000}")
    private Integer redundancyTime;
    /**
     * 如果设备长时间不在线，更新终端为离线状态
     */
    @Async
    @Scheduled(cron = "0 0/1 * * * ?")
    public void deviceOffLine() {
        // job加锁，避免在分布式环境多个应用同时执行任务
        try ( RedisLock lock = redisDistributeLock.getLock(LockConstant.JOB_TASK_EXECUTE_LOCK_PREFIX + this.getClass().getName(),
                LockConstant.DEFAULT_TIMEOUT_MILLS, LockConstant.MAX_RETRY_TIMES, LockConstant.RETRY_INTERVAL_TIME_MILLIS) ){
            if ( null != lock ) {
                logger.debug("Starting deviceOffline schedule...");
                try {
                    Long timeDiff = System.currentTimeMillis() - redundancyTime;

                    // 获取离线设备的唯一编码
                    List<String> offlineDeviceCodes = deviceInfoService.getOffLineDevice(timeDiff);

                    // 添加下线记录
                    if ( offlineDeviceCodes != null && !offlineDeviceCodes.isEmpty() ) {
                        logger.info("添加下线记录:" + JSONObject.toJSONString(offlineDeviceCodes));
                        deviceHeartBeatService.offline(offlineDeviceCodes);
                    }

                    // 设置数据库的设备为离线状态
                    int effect = deviceInfoService.setDeviceOffLine(timeDiff);
                    logger.info("更新超时未访问设备为离线状态，总共更改条数为:" + effect);
                } catch (Exception e) {
                    logger.error("setDeviceOffLine error, the reason : " + e.getMessage(), e);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }
}
